const webdriverio = require('webdriverio')

let driverMap = new Map()
async function createWebDriver(id) {
  const driver = await webdriverio.remote({
    capabilities: {
      browserName: 'chrome',
      'goog:chromeOptions': {
        args: [ 'disable-infobars', 'disable-popup-blocking', 'disable-notifications' ],
        prefs: {
          'profile.managed_default_content_settings.popups' : 1,
          'profile.managed_default_content_settings.notifications' : 1,
        }
      },
    }
  })
  driverMap.set(id, driver)
  return driver
}


async function createWebDriverFirfox(id) {
  const driver = await webdriverio.remote({
    capabilities: {
      browserName: 'firfox',
    }
  })
  driverMap.set(id, driver)
  return driver
}



async function driverGoto(driver, url) {
  await driver.url(url)
}


async function getWebDriver(id) {
  let driver = driverMap.get(id)
  if (driver) {
    return driver
  }
  return await createWebDriver(id)
}


async function driverBack(client) {
  await client.back()
}

async function driverRefresh(client) {
  await client.refresh()
}

async function driverSetCookies(client, cookieStr) {
  const pies = cookieStr.split(";")
  for (let i = 0; i < pies.length; i++) {
    const item = pies[i]
    const kvPair = item.split("=")
    await client.setCookies([
      {name: kvPair[0].trim(), value: kvPair.length == 2 ? kvPair[1].trim() : ""}
    ])
  }
}


async function elemFindItem(driver, css) {
  const elem = driver.$(css)
  await elem.waitForExist({ timeout: 15000 })
  return elem
}

async function elemFindList(driver, css) {
  const elems = driver.$$(css)
  await elems[0].waitForExist({ timeout: 15000 })
  return elems
}


async function elemLocation(elem) {
  return await elem.getLocation()
}

async function elemGetItem(driver, css) {
  const elem = driver.$(css)
  return elem
}

async function elemGetList(driver, css) {
  const elems = driver.$$(css)
  return elems
}

async function elemGetValue(elem) {
  return await elem.getValue()
}

async function elemGetText(elem) {
  return await elem.getText()
}

async function elemExists(client, css) {
  const el = await client.$(css)
  return await el.isExisting()
}

async function elemClick(elem) {
  return await elem.click()
}

async function elemInput(elem, text) {
  await elem.addValue(text)
}

async function elemInputSet(elem, text) {
  await elem.setValue(text)
}

async function elemGetHtml(elem) {
  await elem.getHTML()
}

async function elemWaitUtil(driver, css, asyncFn, timeout = 15000) {
  const elem = await driver.$(css)
  return await elem.waitUntil(
    async function() {
      return await asyncFn(this)
    },
    {
      timeout,
      timeoutMsg: 'elemWaitUtil 超时了'
    })
}

async function elemWaitUtilExist(driver, css, timeout = 15000) {
  return await elemWaitUtil(driver, css, async function(el) {
    return await el.isExisting()
  }, timeout)
}


async function driverScollPage(driver) {
  await driver.keys(['PageDown'])
}

async function driverSendString(driver, s) {
  for (let c of [...s]) {
    await driver.keys([c])
  }
}

async function driverWaitTime(driver, ms) {
  await driver.executeAsync((ms, done) => {
    setTimeout(() => {
      done()
    }, ms)
  }, ms)
}

module.exports = {createWebDriver, getWebDriver, driverGoto, driverBack, driverRefresh, driverSetCookies, elemFindItem, elemFindList, elemLocation, elemGetItem, elemGetList, elemGetValue, elemGetText, elemExists, elemClick, elemInput, elemInputSet, elemGetHtml, elemWaitUtil, elemWaitUtilExist, driverScollPage, driverSendString, driverWaitTime}
